﻿///////////////////////////////////////////////////////////////////////////////
//
// This file is part of the BassDrop project
//   https://code.google.com/p/bass-drop/
//
//
// Creator:	Gergely Krajcsovszki (krajcsovszkig@hotmail.com)
// Date:	2014-01-27 14:10
//
//
// Copyright © 2013-2014. Gergely Krajcsovszki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////////////
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace BassDrop.DesktopClient.Utilities
{
	/// <summary>
	/// String dictionary implementation that can be persisted in a string format using a supplied type converter
	/// </summary>
	/// <remarks> From http://stackoverflow.com/a/1776923/301134 </remarks>
	[System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Usage", "CA2229:ImplementSerializationConstructors" ), TypeConverter( typeof( StringDictionaryTypeConverter ) )]
	public class PersistableStringDictionary : Dictionary<string, string>
	{
	}

	/// <summary>
	/// A type converter that lets you persist a PersistableStringDictionary in a string format
	/// </summary>
	/// <remarks> From http://stackoverflow.com/a/1776923/301134 </remarks>
	public class StringDictionaryTypeConverter : TypeConverter
	{
		public override bool CanConvertFrom(
			ITypeDescriptorContext context,
			Type sourceType )
		{
			if ( sourceType.Equals( typeof( string ) ) )
			{
				return true;
			}

			return base.CanConvertFrom( context, sourceType );
		}

		public override bool CanConvertTo(
			ITypeDescriptorContext context,
			Type destinationType )
		{
			if ( destinationType.Equals( typeof( string ) ) )
			{
				return true;
			}

			return base.CanConvertTo( context, destinationType );
		}

		public override object ConvertFrom(
			ITypeDescriptorContext context,
			CultureInfo culture,
			object value )
		{
			if ( value is string )
			{
				PersistableStringDictionary sd = new PersistableStringDictionary();

				XDocument xs = XDocument.Load( new StringReader( value as string ) );

				foreach ( var item in xs.Descendants( "entry" ) )
				{
					sd.Add( item.Element( "key" ).Value, item.Element( "value" ).Value );
				}

				return sd;
			}

			return base.ConvertFrom( context, culture, value );
		}

		public override object ConvertTo(
			ITypeDescriptorContext context,
			CultureInfo culture,
			object value,
			Type destinationType )
		{
			if ( destinationType.Equals( typeof( string ) ) )
			{
				PersistableStringDictionary sd = value as PersistableStringDictionary;

				StringBuilder sb = new StringBuilder();

				sb.Append( "<persistableStringDictionary>" );
				foreach ( var item in sd )
				{
					sb.AppendFormat(
						"<entry><key>{0}</key><value>{1}</value></entry>",
						item.Key,
						item.Value );
				}
				sb.Append( "</persistableStringDictionary>" );

				return sb.ToString();
			}

			return base.ConvertTo( context, culture, value, destinationType );
		}
	}
}
